package com.lizemin.websocketserver.handler;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * websocket 处理器
 *
 * @author lizemin
 * @version 1.0
 */
public class SimpleWebSocketServerHandler extends TextWebSocketHandler {

    private final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>();

    public SimpleWebSocketServerHandler() {
        // 启动定时任务，每隔 1 秒执行一次
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(this::sendCurrentTime, 0, 10, TimeUnit.SECONDS);
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
        System.out.println("已建立新连接: " + session.getId());
    }

    /**
     * 会话状态:
     * 打开状态（Open）：当客户端和服务器成功完成 WebSocket 握手过程后，会话就进入打开状态。在这个状态下，客户端和服务器能双向发送和接收数据。好比两人拨通电话，能自由交流。
     * 关闭状态（Closed）：会话关闭可能是客户端或服务器主动关闭连接，也可能因网络问题等异常情况导致。处于关闭状态时，不能再发送或接收数据，如同电话挂断。
     * 正在关闭状态（Closing）：当一方发起关闭连接请求，会话进入正在关闭状态，此时连接还未完全关闭，但通常不再接收新数据，类似一方准备挂断电话。
     *
     * @param session 会话
     * @param message 消息
     * @throws Exception 异常
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("收到消息: " + payload);
        // 广播消息给所有客户端
        for (WebSocketSession se : sessions) {
            // 检查当前 WebSocket 会话是否处于打开状态
            if (se.isOpen()) {
                se.sendMessage(new TextMessage("服务器回复: " + payload));
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        System.out.println("连接关闭: " + session.getId());
    }

    /**
     * 向所有连接的客户端发送当前时间
     */
    private void sendCurrentTime() {
        // 获取当前时间并格式化为 yyyy-MM-dd HH:mm:ss 格式
        String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        TextMessage timeMessage = new TextMessage("当前时间: " + currentTime);
        for (WebSocketSession session : sessions) {
            try {
                if (session.isOpen()) {
                    session.sendMessage(timeMessage);
                }
            } catch (Exception e) {
                System.err.println("发送时间消息时出错: " + e.getMessage());
            }
        }
    }

    public void sendMessage(String message) {
        for (WebSocketSession session : sessions) {
            try {
                if (session.isOpen()) {
                    session.sendMessage(new TextMessage(message));
                }
            } catch (Exception e) {
                System.err.println("发送消息时出错: " + e.getMessage());
            }
        }
    }
}
